package com.dtagri.fjwlw.util;

import org.MediaPlayer.PlayM4.Player;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View.OnClickListener;
import android.widget.ScrollView;

import com.dtagri.fjwlw.R;
import com.dtagri.fjwlw.bean.TjNvr;
import com.dtagri.fjwlw.ui.VideoCenterActivity;
import com.hikvision.netsdk.ExceptionCallBack;
import com.hikvision.netsdk.HCNetSDK;
import com.hikvision.netsdk.NET_DVR_DEVICEINFO_V30;
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO;
import com.hikvision.netsdk.PTZCommand;
import com.hikvision.netsdk.RealPlayCallBack;

/**
 * 海康视频帮助类
 * 
 * @author wxjn
 * 
 */
public class HKVideoHelper implements Callback {
	private SurfaceView m_osurfaceView = null;
	private long mLastTime=0,mCurTime;
	private NET_DVR_DEVICEINFO_V30 m_oNetDvrDeviceInfoV30 = null;

	private int m_iLogID = -1; // return by NET_DVR_Login_v30
	private int m_iPlayID = -1; // return by NET_DVR_RealPlay_V30

	private int m_iPort = -1; // play port
	private int m_iStartChan = 0; // start channel no
	public static int state;//0竖屏 1横屏
	private final static String TAG = "HKVideoHelper";
	private ScrollView scrollView;
	private Integer sschanelnum;

	public HKVideoHelper(Context context, SurfaceView surfaceView) {
		this.m_osurfaceView = surfaceView;
		surfaceView.getHolder().addCallback(this);

	}

	// @Override
	public void surfaceCreated(SurfaceHolder holder) {
		m_osurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
		state=0;

		Log.i(TAG, "surface is created" + m_iPort);
		if (-1 == m_iPort) {
			return;
		}
		Surface surface = holder.getSurface();
		if (true == surface.isValid()) {
			if (false == Player.getInstance()
					.setVideoWindow(m_iPort, 0, holder)) {
				Log.e(TAG, "Player setVideoWindow failed!");
			}
		}
	}

	// @Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	// @Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		Log.i(TAG, "Player setVideoWindow release!" + m_iPort);
		if (-1 == m_iPort) {
			return;
		}
		if (true == holder.getSurface().isValid()) {
			if (false == Player.getInstance().setVideoWindow(m_iPort, 0, null)) {
				Log.e(TAG, "Player setVideoWindow failed!");
			}
		}
	}

	@SuppressLint("SdCardPath")
	public static boolean initeSdk() {
		// init net sdk
		if (!HCNetSDK.getInstance().NET_DVR_Init()) {
			Log.e(TAG, "HCNetSDK init is failed!");
			return false;
		}
		HCNetSDK.getInstance().NET_DVR_SetLogToFile(3, "/mnt/sdcard/sdklog/",
				true);
		return true;
	}

	private void startSinglePreview() {
		RealPlayCallBack fRealDataCallBack = getRealPlayerCbf();
		if (fRealDataCallBack == null) {
			Log.e(TAG, "fRealDataCallBack object is failed!");
			return;
		}
		Log.i(TAG, "m_iStartChan:" + m_iStartChan);

		NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();
		previewInfo.lChannel = m_iStartChan + sschanelnum - 1;
		previewInfo.dwStreamType = 1; // substream
		previewInfo.bBlocked = 1;
		// HCNetSDK start preview
		m_iPlayID = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(m_iLogID,
				previewInfo, fRealDataCallBack);
		if (m_iPlayID < 0) {
			Log.e(TAG, "NET_DVR_RealPlay is failed!Err:"
					+ HCNetSDK.getInstance().NET_DVR_GetLastError());
			return;
		}

		Log.i(TAG,
				"NetSdk Play sucess ***********************3***************************");
	}

	public void stopSinglePlayer() {
		Player.getInstance().stopSound();
		// player stop play
		if (!Player.getInstance().stop(m_iPort)) {
			Log.e(TAG, "stop is failed!");
			return;
		}

		if (!Player.getInstance().closeStream(m_iPort)) {
			Log.e(TAG, "closeStream is failed!");
			return;
		}
		if (!Player.getInstance().freePort(m_iPort)) {
			Log.e(TAG, "freePort is failed!" + m_iPort);
			return;
		}
		m_iPort = -1;
	}

	private void stopSinglePreviewAndRestart() {
		if (m_iPlayID < 0) {
			Log.e(TAG, "m_iPlayID < 0");
			return;
		}

		// net sdk stop preview
		if (!HCNetSDK.getInstance().NET_DVR_StopRealPlay(m_iPlayID)) {
			Log.e(TAG, "StopRealPlay is failed!Err:"
					+ HCNetSDK.getInstance().NET_DVR_GetLastError());
			return;
		}

		m_iPlayID = -1;
		stopSinglePlayer();
		startSinglePreview();
	}

	private int loginDevice(TjNvr nvr) {
		// get instance
		m_oNetDvrDeviceInfoV30 = new NET_DVR_DEVICEINFO_V30();
		if (null == m_oNetDvrDeviceInfoV30) {
			Log.e(TAG, "HKNetDvrDeviceInfoV30 new is failed!");
			return -1;
		}
		String strIP = nvr.getNvrwanip();
		int aPort = Integer.parseInt(nvr.getAppDataPort());
		String strUser = nvr.getNvrusername();
		String strPsd = nvr.getNvruserpwd();
		// call NET_DVR_Login_v30 to login on, port 8000 as default
		int iLogID = HCNetSDK.getInstance().NET_DVR_Login_V30(strIP, aPort,
				strUser, strPsd, m_oNetDvrDeviceInfoV30);
		
		if (iLogID < 0) {
			Log.e(TAG, "NET_DVR_Login is failed!Err:"
					+ HCNetSDK.getInstance().NET_DVR_GetLastError());
			return -1;
		}
		if (m_oNetDvrDeviceInfoV30.byChanNum > 0) {
			m_iStartChan = m_oNetDvrDeviceInfoV30.byStartChan;
		} else if (m_oNetDvrDeviceInfoV30.byIPChanNum > 0) {
			m_iStartChan = m_oNetDvrDeviceInfoV30.byStartDChan;
		}
		Log.i(TAG, "NET_DVR_Login is Successful!");

		return iLogID;
	}

	private ExceptionCallBack getExceptiongCbf() {
		ExceptionCallBack oExceptionCbf = new ExceptionCallBack() {
			public void fExceptionCallBack(int iType, int iUserID, int iHandle) {
				System.out.println("recv exception, type:" + iType);
			}
		};
		return oExceptionCbf;
	}

	private RealPlayCallBack getRealPlayerCbf() {
		RealPlayCallBack cbf = new RealPlayCallBack() {
			public void fRealDataCallBack(int iRealHandle, int iDataType,
					byte[] pDataBuffer, int iDataSize) {
				// player channel 1
				HKVideoHelper.this.processRealData(1, iDataType, pDataBuffer,
						iDataSize, Player.STREAM_REALTIME);
			}
		};
		return cbf;
	}

	public void processRealData(int iPlayViewNo, int iDataType,
			byte[] pDataBuffer, int iDataSize, int iStreamMode) {
		if (HCNetSDK.NET_DVR_SYSHEAD == iDataType) {
			if (m_iPort >= 0) {
				return;
			}
			m_iPort = Player.getInstance().getPort();
			if (m_iPort == -1) {
				Log.e(TAG, "getPort is failed with: "
						+ Player.getInstance().getLastError(m_iPort));
				return;
			}
			Log.i(TAG, "getPort succ with: " + m_iPort);
			if (iDataSize > 0) {
				if (!Player.getInstance().setStreamOpenMode(m_iPort,
						iStreamMode)) // set stream mode
				{
					Log.e(TAG, "setStreamOpenMode failed");
					return;
				}
				if (!Player.getInstance().openStream(m_iPort, pDataBuffer,
						iDataSize, 2 * 1024 * 1024)) // open stream
				{
					Log.e(TAG, "openStream failed");
					return;
				}
				if (!Player.getInstance().play(m_iPort,
						m_osurfaceView.getHolder())) {
					Log.e(TAG, "play failed");
					return;
				}
				if (!Player.getInstance().playSound(m_iPort)) {
					Log.e(TAG, "playSound failed with error code:"
							+ Player.getInstance().getLastError(m_iPort));
					return;
				}
			}
		} else {
			if (!Player.getInstance()
					.inputData(m_iPort, pDataBuffer, iDataSize)) {
				// Log.e(TAG, "inputData failed with: " +
				// Player.getInstance().getLastError(m_iPort));
			}

		}

	}

	public void Cleanup() {
		// release player resource

		Player.getInstance().freePort(m_iPort);
		m_iPort = -1;

		// release net SDK resource
		HCNetSDK.getInstance().NET_DVR_Cleanup();
	}

	public void reLogin(TjNvr nvr) {
		try {
			if (m_iLogID < 0) {
				login(nvr);
			} else {
				// whether we have logout
				if (!HCNetSDK.getInstance().NET_DVR_Logout_V30(m_iLogID)) {
					Log.e(TAG, " NET_DVR_Logout is failed!");
					return;
				}
				m_iLogID = -1;
				login(nvr);
			}
		} catch (Exception err) {
			Log.e(TAG, "error: " + err.toString());
		}
	}

	public void login(TjNvr nvr) {
		initeSdk();
		// login on the device
		m_iLogID = loginDevice(nvr);
		if (m_iLogID < 0) {
			TToast.showToastShort("NVR登录失败");
			return;
		}
		// get instance of exception callback and set
		ExceptionCallBack oexceptionCbf = getExceptiongCbf();
		if (oexceptionCbf == null) {
			Log.e(TAG, "ExceptionCallBack object is failed!");
			return;
		}

		if (!HCNetSDK.getInstance().NET_DVR_SetExceptionCallBack(oexceptionCbf)) {
			Log.e(TAG, "NET_DVR_SetExceptionCallBack is failed!");
			return;
		}

		Log.i(TAG,
				"Login sucess ****************************1***************************");
	}

	public void preview(Integer sschanelnum) {
		this.sschanelnum = sschanelnum;
		try {
			if (m_iLogID < 0) {
				Log.e(TAG, "please login on device first");
				return;
			}
			if (m_iPlayID < 0) {
				startSinglePreview();
			} else {
				stopSinglePreviewAndRestart();
			}
		} catch (Exception err) {
			Log.e(TAG, "error: " + err.toString());
		}
	}

	/**
	 * 云台控制
	 * 
	 * @param event
	 * @param m_bPTZL
	 * @return
	 */
	public boolean ptz(MotionEvent event, boolean m_bPTZL) {
		try {
			if (m_iLogID < 0) {
				Log.e(TAG, "please login on a device first");
				return false;
			}
			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				if (m_bPTZL == false) {
					if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
							m_iLogID, m_iStartChan + sschanelnum - 1,
							PTZCommand.PAN_LEFT, 0)) {
						Log.e(TAG, "start PAN_LEFT failed with error code: "
								+ HCNetSDK.getInstance().NET_DVR_GetLastError());
					} else {
						Log.i(TAG, "start PAN_LEFT succ");
					}
				} else {
					if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
							m_iLogID, m_iStartChan + sschanelnum - 1,
							PTZCommand.PAN_RIGHT, 0)) {
						Log.e(TAG, "start PAN_RIGHT failed with error code: "
								+ HCNetSDK.getInstance().NET_DVR_GetLastError());
					} else {
						Log.i(TAG, "start PAN_RIGHT succ");
					}
				}
			} else if (event.getAction() == MotionEvent.ACTION_UP) {
				if (m_bPTZL == false) {
					if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
							m_iLogID, m_iStartChan + sschanelnum - 1,
							PTZCommand.PAN_LEFT, 1)) {
						Log.e(TAG, "stop PAN_LEFT failed with error code: "
								+ HCNetSDK.getInstance().NET_DVR_GetLastError());
					} else {
						Log.i(TAG, "stop PAN_LEFT succ");
					}
				} else {
					if (!HCNetSDK.getInstance().NET_DVR_PTZControl_Other(
							m_iLogID, m_iStartChan + sschanelnum - 1,
							PTZCommand.PAN_RIGHT, 1)) {
						Log.e(TAG, "stop PAN_RIGHT failed with error code: "
								+ HCNetSDK.getInstance().NET_DVR_GetLastError());
					} else {
						Log.i(TAG, "stop PAN_RIGHT succ");
					}
				}
			}
			return true;
		} catch (Exception err) {
			Log.e(TAG, "error: " + err.toString());
			return false;
		}
	}
	//视频大小信息处理
	public class SuitHandler extends Handler{
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
		}
		
		
	}

}
